package com.pangda.aop;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pangda.common.domain.ResponseResult;
import com.pangda.common.utils.UserContext;
import com.pangda.pojo.OperationLog;
import com.pangda.pojo.SysUser;
import com.pangda.service.IOperationLogService;
import com.pangda.service.ISysUserService;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class LogAspect {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private IOperationLogService operationLogService;

    @Autowired
    private ISysUserService sysUserService;

    // 定义一个包含的切入点表达式，匹配com.pangda.controller包下的所有类
    @Pointcut("execution(* com.pangda.controller..*(..))")
    public void controllerMethods() {
    }

    // 定义一个排除的切入点表达式，匹配LoginController类下的所有方法
    @Pointcut("execution(* com.pangda.controller.LoginController.*(..))")
    public void excludeLoginControllerMethods() {
    }

    @Pointcut("execution(* com.pangda.controller.OperationLogController.*(..))")
    public void excludeControllerMethods() {
    }

    // 结合使用上面两个切入点，排除LoginController
    @Around("controllerMethods() && !excludeLoginControllerMethods()&&!excludeControllerMethods()")
    public Object logAroundOtherControllers(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取方法类型
        String requestMethod = request.getMethod();
        if ("GET".equals(requestMethod)) {
            return joinPoint.proceed();
        }
        // 这里是你的环绕通知逻辑
        String userName = UserContext.getUser();
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUserName, userName);
        SysUser user = sysUserService.getOne(wrapper);
        //获取类名
        String className = joinPoint.getTarget().getClass().getName();
        Class<?> aClass = Class.forName(className);
        Api api = aClass.getAnnotation(Api.class);
        String tag = api.tags()[0];
        //操作方法名
        String methodName = joinPoint.getSignature().toString();
        //获取登录Ip
        String ip = request.getRemoteAddr();

        //获取uri
        String uri = request.getRequestURI();

        //获取参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

        Object res = joinPoint.proceed();


        String returnValue = JSONUtil.toJsonStr(res);

        OperationLog operationLog = new OperationLog();
        ResponseResult result = BeanUtil.toBean(res, ResponseResult.class);
        result.getCode();
        if (result.getCode() == 200) {
            operationLog.setStatus(0);
        } else {
            operationLog.setStatus(1);
            operationLog.setErrorMsg(result.getMsg());
        }

        operationLog.setOperName(userName);
        operationLog.setOperParam(methodParams);
        operationLog.setTitle(tag);
        operationLog.setCreateTime(LocalDateTime.now());
        operationLog.setOperTime(LocalDateTime.now());
        operationLog.setOperIp(ip);
        operationLog.setRequestMethod(requestMethod);
        operationLog.setBusinessType(1);
        operationLog.setMethod(methodName);
        operationLog.setOperUrl(uri);
        operationLog.setOperatorType(1);
        operationLog.setJsonResult(returnValue);
        operationLogService.save(operationLog);
        return res;
    }

}
